﻿using System;

namespace DelegateDemo
{
    //定义委托，它定义了可以代表的方法的类型
    public delegate void GreetingDelegate(string name);

    public class GreetingManager
    {
        //在GreetingManager类的内部声明GreetingDelegate变量
        public GreetingDelegate myDelegate;

        //注册一个事件
        public event GreetingDelegate MakeGreet;

        public void GreetPeople(string name, GreetingDelegate MakeGreeting)
        {
            MakeGreeting(name);
        }

        //改造GreetPeople方法
        public void GreetPeople(string name)
        {
            if (myDelegate != null)
            {
                myDelegate(name);
            }
        }

        //使用事件
        public void GreetPeopleEvent(string name)
        {
            MakeGreet(name);
        }
    }

    class Program
    {
        private static void EnglishGreeting(string name)
        {
            Console.WriteLine("Morning, {0}", name);
        }

        private static void ChineseGreeting(string name)
        {
            Console.WriteLine("早上好, {0}", name);
        }

        //注意此方法，它接受一个GreetingDelegate类型的方法作为参数
        private static void GreetPeople(string name, GreetingDelegate MakeGreeting)
        {
            MakeGreeting(name);
        }

        static void Main(string[] args)
        {
            //传入的方法，必须跟定义的委托一致
            //即：有同样的返回值，同样的传入参数
            GreetPeople("Ken", EnglishGreeting);
            GreetPeople("程序猿", ChineseGreeting);
            Console.WriteLine("------------------------------------------------------");

            //可以把方法当作变量赋值给委托
            GreetingDelegate delegate1, delegate2;
            delegate1 = EnglishGreeting;
            delegate2 = ChineseGreeting;
            GreetPeople("Ken", delegate1);
            GreetPeople("程序猿", delegate2);
            Console.WriteLine("------------------------------------------------------");

            //可以将多个方法绑定到一个委托，程序会按顺序执行委托中的方法
            GreetingDelegate delegate3;
            delegate3 = EnglishGreeting;
            delegate3 += ChineseGreeting;
            GreetPeople("Ken", delegate3);
            Console.WriteLine("------------------------------------------------------");

            //可以也可以绕过GreetPeople方法，通过委托来直接调用EnglishGreeting和ChineseGreeting
            GreetingDelegate delegate4;
            delegate4 = EnglishGreeting;
            delegate4 += ChineseGreeting;
            delegate4("Ken");
            Console.WriteLine("------------------------------------------------------");

            //也可以直接new一个委托，然后把方法当参数传入
            GreetingDelegate delegate5 = new GreetingDelegate(EnglishGreeting);
            delegate5 += ChineseGreeting;
            delegate5("Ken");
            Console.WriteLine("------------------------------------------------------");

            //也可以取消委托方法绑定
            GreetingDelegate delegate6 = new GreetingDelegate(EnglishGreeting);
            delegate6 += ChineseGreeting;
            delegate6("Ken");

            delegate6 -= EnglishGreeting;
            delegate6("程序猿");
            Console.WriteLine("------------------------------------------------------");

            //类中的方法
            GreetingManager gm = new GreetingManager();
            gm.GreetPeople("Ken", EnglishGreeting);
            gm.GreetPeople("程序猿", ChineseGreeting);
            Console.WriteLine("------------------------------------------------------");

            //将多个方法绑定到委托
            GreetingManager gm2 = new GreetingManager();
            GreetingDelegate delegate7;
            delegate7 = EnglishGreeting;
            delegate7 += ChineseGreeting;
            gm2.GreetPeople("Ken", delegate7);
            Console.WriteLine("------------------------------------------------------");

            //调用GreetingManager类中的GreetingDelegate变量
            GreetingManager gm3 = new GreetingManager();
            gm3.myDelegate = EnglishGreeting;
            gm3.myDelegate += ChineseGreeting;
            gm3.GreetPeople("Ken", gm3.myDelegate);
            Console.WriteLine("------------------------------------------------------");

            //通过委托调用方法
            GreetingManager gm4 = new GreetingManager();
            gm4.myDelegate = EnglishGreeting;
            gm4.myDelegate += ChineseGreeting;
            gm4.GreetPeople("Ken");
            Console.WriteLine("------------------------------------------------------");

            //使用事件
            GreetingManager gm5 = new GreetingManager();
            gm5.MakeGreet += EnglishGreeting;
            gm5.MakeGreet += ChineseGreeting;
            gm5.GreetPeopleEvent("Ken");

            Console.ReadKey();
        }
    }
}
